package com.erastep.mvc
{
	import com.erastep.mvc.ifc.IFrame;
	import com.erastep.mvc.ifc.IMedator;
	import com.erastep.mvc.ifc.IModule;
	import com.erastep.mvc.ifc.IProxy;
	import com.erastep.mvc.mediator.Mediator;
	import com.erastep.mvc.module.vo.ModuleVO;
	import com.erastep.mvc.observer.Notification;
	import com.erastep.mvc.proxy.Proxy;
	import com.erastep.util.CommonConstants;
	import com.erastep.util.LogUtil;
	import com.erastep.util.StringUtil;
	
	import flash.external.ExternalInterface;
	
	import mx.controls.Alert;

    /**
	 * 核心消息控制类
	 * @author Jarvis
	 * @date 2011/04/07
	 * @depart NB
	 * */
	public class EraStepFrame implements IFrame
	{
		
		public function EraStepFrame()
		{
			instance=this;
			pluginMap = new Array();
			mediatorMap = new Array();
			proxyMap = new Array();
			_tempSendData = new Object();
		}
		
		/**
		 * notificaiton center all message send here and do some thing at here.
		 * */
		public function sendNotification(notificationName:String, body:Object=null, type:String=null, toId:String=null, fromId:String=null):void
		{
			//LogUtil.print("消息名称::"+notificationName+"  消息类型::"+type+"   外壳类型:"+FrameType);
			try
			{
				if (toId)
				{
					if (toId == CommonConstants.VICTOPFRAME)
					{
						methodHandler(notificationName, body, type, toId, fromId);
					}
					else if(toId == CommonConstants.MODULE)
					{
						//instance the module
						instanceModule(notificationName,type).execute(new Notification(notificationName, body, type, toId, fromId));
					}else if(toId.substr(0,2) == "PT"){
						sendNotification("messageToPotal",{messageName:notificationName,body:body,toId:toId},type,CommonConstants.HOMEPAGE);
					}else{
						//当消息穿透到其他模块中，如果moduleKey 为空或者null 默认值为 0
						var im:IModule;
						var _temp:Array;
						if(toId.indexOf("_") != -1){
							_temp = toId.split("_");
							if(_temp.length > 2){
								Alert.show(_temp+" 模块ID规则错误,弃掉消息!","提示");
							}
						}
						if(_temp && _temp.length == 2){
							im = retrieveModule(_temp[0],_temp[1]);
						}else{
							if(toId == CommonConstants.HOMEPAGE){
								type = null;
							}
							im = retrieveModule(toId,type);
						}
						if(im != null){
							im.executeMessage(notificationName, body, type, toId, fromId)			
						}else{
							Alert.show("未找到插件 "+ toId +",弃掉消息!","提示");
						}
					}
				}
				else
				{
					methodHandler(notificationName, body, type, toId, fromId);
				}
			} 
			catch(error:Error) 
			{
				LogUtil.print("执行消息失败!\n"+error.getStackTrace());
			}
			
		}

		/**
		 * do method
		 * */
		private function methodHandler(note:String, body:Object, type:String, toId:String, fromId:String):void
		{
			var func:Function;
			var listFun:Array=new Array();
			//check this frame
			if (hasOwnProperty(StringUtil.getMethodName(note)))
			{
				func=this[StringUtil.getMethodName(note)] as Function;
				if (func != null)
				{
					listFun.push(func);
				}
			}
			//check mediator 
			for each (var md:Mediator in mediatorMap)
			{
				/*if(md.getMediatorName() == DataStoreController.NAME){
					//跳过数据通道的消息实例
					continue;
				}*/
				if (md.hasOwnProperty(StringUtil.getMethodName(note)))
				{
					func=md[StringUtil.getMethodName(note)] as Function;
					if (func != null)
					{
						listFun.push(func);
					}
				}
			}
			//check all proxy
			for each(var py:Proxy in proxyMap){
				if(py.hasOwnProperty(StringUtil.getMethodName(note))){
					func = py[StringUtil.getMethodName(note)] as Function;
					if(func != null){
						listFun.push(func);
					}
				}			
			}
			
			if (listFun.length > 0)
			{
				for each (func in listFun)
				{
					func.call(null, new Notification(note, body, type,toId,fromId)); //call function
				}
			}
			else
			{
				    LogUtil.print("Can not find << "+StringUtil.getMethodName(note) +" >> Method_Victop!");
					Alert.show(CommonConstants.WORMING_MESSAGE + " <<" + StringUtil.getMethodName(note) + ">>  Method_Victop!", CommonConstants.WORMING_TITLE);
			}
		}
		

		public static function getInstance():IFrame
		{
			if (instance == null)
				instance=new EraStepFrame();
			return instance;
		}

		/***
		 * register module
		 * */
		public function registerModule(comandName:String, command:Class):void
		{
			// do not allow re-registration (you must to removeMediator fist)
			if (pluginMap[comandName] != null)
				return;

			// Register the Mediator for retrieval by name
			pluginMap[comandName] = command;

			// alert the mediator that it has been registered
		}
		/**
		 * @param proxy 
		 * */
		public function registerProxy(proxy:IProxy):void{
			// do not allow re-registration (you must to removeMediator fist)
			if ( proxyMap[ proxy.getProxyName() ] != null ) return;
			
			// Register the Mediator for retrieval by name
			proxyMap[ proxy.getProxyName() ] = proxy;
			proxy.host = _host;
			proxy.onRegister()
			// alert the mediator that it has been registered
		}
		/** 
		 * remove proxy
		 * */
		public function removeProxy(_proxyName:String):void{
			// do not allow re-registration (you must to removeMediator fist)
			if ( proxyMap[ _proxyName ]  == null)
				return;
			
			var _proxy:IProxy = proxyMap[ _proxyName ] as IProxy;
			_proxy.onRemove();
			_proxy = null;
			proxyMap[ _proxyName ] = null;
			delete proxyMap[ _proxyName ];
		}
		/**
		 * retrive proxy
		 * */
		public function retriveProxy(proxyName:String):IProxy{
			if ( proxyMap[ proxyName ]  == null)
				return null; 	
		    return proxyMap[ proxyName ] as IProxy;
		}
		/***
		 * register test module
		 * */
		public function registerTestModule(moduleId:String, command:Class,param:Object = null):void
		{
			// do not allow re-registration (you must to removeMediator fist)
			if (pluginMap[moduleId] != null)
				return;
			
			// Register the Mediator for retrieval by name
			pluginMap[moduleId]=command;
			
			
			var module:ModuleVO = new ModuleVO();
			module.resourceid = moduleId;
			if(param){
				module.formid = param.formId;
				module.systemid = param.systemId;
			}
			if(pluginList == null){
				var templist:Array = new Array();
				templist.push(module);
				templist[module.systemid+"#"+module.formid] = module;
				this.pluginList = templist;
			}else{
				this.pluginList[module.systemid+"#"+module.formid] = module;
				this.pluginList.push(module);
			}
			
			// alert the mediator that it has been registered
		}

		public function retrieveModule(comandName:String,moduleKey:String = null):IModule
		{
			var tempvo:ModuleVO = findTemplateVoById(comandName) as ModuleVO;
			if (tempvo != null)
			{
				var module:IModule;
				
				if(!moduleKey || StringUtil.trim(moduleKey) ==""){
					moduleKey = "0";		
				}
				//初始化对象
				if (pluginMap[comandName+"_"+moduleKey] == null)
				{
					return instanceModule(comandName,moduleKey);
				}
				else
				{
					//获取初始化对象
					return pluginMap[comandName+"_"+moduleKey] as IModule;
				}
			}
			else
			{
				LogUtil.print("未找到任何此插件的信息!");
				return null;
			}
		}
		
		/**
		 * 实例化插件对象
		 * */
		private function instanceModule(comandName:String,moduleKey:String = null):IModule{
			if(!moduleKey || StringUtil.trim(moduleKey) ==""){
				moduleKey = "0";		
			}
			try
			{
				//找到初始注册的类
				var plugin:Class = pluginMap[comandName] as Class;
				//此处开始初始化接口
				var module:IModule = new plugin(comandName+"_"+moduleKey) as IModule;
				//服务器端地址注入
				module.setHostUrl(_host);
				//插件唯一标识值设置
				pluginMap[comandName+"_"+moduleKey] = module;
				return module;
			} 
			catch(error:Error) 
			{
				LogUtil.print("初始化插件失败!\n"+error.getStackTrace());
			}
			return null;
		}
		
		/**
		 * has loaded module
		 * */
		public function hasLoadedModule(resourceId:String):Boolean{
			if (pluginMap[resourceId] == null)
			{
				return false;
			}else{
			    return true;
			}
		}

		/**
		 * register mediator
		 * */
		public function registerMediator(mediator:IMedator):void
		{
			// do not allow re-registration (you must to removeMediator fist)
			if (mediatorMap[mediator.getMediatorName()] != null)
				return;

			// Register the Mediator for retrieval by name
			mediatorMap[mediator.getMediatorName()]=mediator;
            
			// alert the mediator that it has been registered
			mediator.onRegister();
			//set host url
			mediator.host = this._host;
			
		}
		/**
		 * remove mediator
		 * */
		public function removeMediator(_mediatorName:String):void{
			// do not allow re-registration (you must to removeMediator fist)
			if (mediatorMap[_mediatorName] == null)
				return;
			
			var _mediator:Mediator = mediatorMap[_mediatorName] as Mediator;
			_mediator.onRemove();
			_mediator = null;
			mediatorMap[_mediatorName] = null;
			delete mediatorMap[_mediatorName ];
		}

		/**
		 * retrive mediator
		 * */
		public function retriveMediator(mediatorName:String):IMedator{
			if (mediatorMap[mediatorName] != null)
				return mediatorMap[mediatorName] as IMedator;
			return null;
		}
		
		/**
		 * find resource by module id and 
		 * */
		public function getResourceById(moduleId:String,resourceId:String):Object{
			return resourceList[moduleId][resourceId];
		}
		
		
		protected static var instance:IFrame;

		//command array
		private var pluginMap:Array;

		//mediator array
		private var mediatorMap:Array;

		//proxy array
		private var proxyMap:Array;

		//module list
		public var pluginList:Array;
		
		//server url
		private var _host:String;
		
		public var userInfo:Object;
		
		private var _tempSendData:Object;
		
		private var resourceList:Object = new Object();;
		
		/**
		 * 
		 * */
		public function get tempSendData():Object{
			return _tempSendData;
		}
		/**
		 * 开始销毁插件
		 * */
		public function destroyPlugin(id:String):void{
			if(pluginMap.hasOwnProperty(id)){
				var temp:IModule = 	pluginMap[id] as IModule;
				var tempArr:Array;
				for each(var ip:IProxy in temp.proxys){
					temp.removeProxy(ip.getProxyName());
				}
				for each(var im:IMedator in temp.mediators){
					temp.removeMediator(im.getMediatorName());
				}
				temp = null;
				delete pluginMap[id];
				LogUtil.print("结束销毁插件 "+id);
			}
		}
		/**
		 * 通过ID来寻找模版 
		 **/
		private function findTemplateVoById(id:String):ModuleVO
		{
			var temp:ModuleVO = null; 
			for each(temp in pluginList){
				if(temp.resourceid == StringUtil.trim(id)){
					return temp;
				}
			}
			return temp;
		}
		
		public function findDataByPluginId(plugingId:String):ModuleVO{
			return findTemplateVoById(plugingId);
		}
		
		/**
		 * 通过 formId 和 systemId 来寻找模版
		 * */
		public function findTemplateVoBySF(systemId:int,formId:int):ModuleVO{
			if(pluginList.hasOwnProperty(systemId+"#"+formId)){
				return pluginList[systemId+"#"+formId] as ModuleVO;
			}
			return null;
		}
		
		
		public function set host(host:String):void{
			this._host = host;
			//完成链接注入后，开始注册
		}
		
		public function get host():String{
			return this._host;
		}
		
		public function get user():Object{
			return userInfo;
		}
		
		public  function wrapUrl():String
		{
			// will update to parse to media server url.
			// TEMP TODO  just for video url prototype
			var urlFix:String;
			var result:String = "",url:String = "";
		
			if (! urlFix)
			{
				urlFix = ExternalInterface.call("function getURL(){return window.location.href;}");
			}
			if (urlFix &&(  (urlFix.substr(0,4)== "http") || (urlFix.substr(0,4)== "HTTP")) )
			{
				for (var i:int = 0;i<urlFix.length; i++)
				{
					if (urlFix.charAt(i) == "/" && urlFix.charAt(i-1) != "/" && urlFix.charAt(i+1) != "/")
					{
						urlFix = urlFix.substring(0,i);
						break;
					}
				}
				result = urlFix + url;
			}else{
				result = url;
			}
		
			//			trace('urlFixResult:' + result);
			return result;
		}
	}
}